﻿//  Copyright © 2009-2010 by Rhy A. Mednick
//  All rights reserved.
//  http://rhyduino.codeplex.com
//  
//  Redistribution and use in source and binary forms, with or without modification, 
//  are permitted provided that the following conditions are met:
//  
//  * Redistributions of source code must retain the above copyright notice, this list 
//    of conditions and the following disclaimer.
//  
//  * Redistributions in binary form must reproduce the above copyright notice, this 
//    list of conditions and the following disclaimer in the documentation and/or other 
//    materials provided with the distribution.
//  
//  * Neither the name of Rhy A. Mednick nor the names of its contributors may be used 
//    to endorse or promote products derived from this software without specific prior 
//    written permission.
//  
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
//  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
//  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
//  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
//  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
//  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
//  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
//  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
//  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Rhyduino.Test
{
    [TestClass]
    public class ExtensionMethodTests
    {
        #region Public Methods

        /// <summary>
        ///   Verify that the ToHexString method functions as expected.
        /// </summary>
        [TestMethod]
        public void ToHexString_Functionality()
        {
            var value = new byte[] {0x00, 0x01, 0xF0};
            Assert.AreEqual("Byte[3]{00 01 F0}", value.ToHexString());

            value = new byte[] {};
            Assert.AreEqual("Byte[0]{}", value.ToHexString());

            value = new byte[] {0xA3, 0xB1, 0x12, 0x17, 0x32, 0xEE, 0x00, 0x00, 0x00};
            Assert.AreEqual("Byte[9]{A3 B1 12 17 32 EE 00 00 00}", value.ToHexString());
        }

        /// <summary>
        ///   Verify that the proper exception is thrown when we call ToHexString with a null array.
        /// </summary>
        [TestMethod]
        public void ToHexString_Null()
        {
            var caught = false;
            byte[] nullArray = null;

            try
            {
                nullArray.ToHexString();
            }
            catch (ArgumentNullException)
            {
                caught = true;
            }
            finally
            {
                if (!caught)
                {
                    Assert.Fail("Did not receive the expected exception.");
                }
            }
        }

        /// <summary>
        ///   Verify that the ToTwo7BitBytes method functions as expected.
        /// </summary>
        [TestMethod]
        public void ToTwo7BitBytes_Functionality()
        {
            var testValues = new[] {-1, 0, 1, 250, 500, 1000, 3000};
            var expectedResults = new[]
                                      {
                                          new byte[] {0x7F, 0x7F},
                                          new byte[] {0x00, 0x00},
                                          new byte[] {0x01, 0x00},
                                          new byte[] {0x7A, 0x01},
                                          new byte[] {0x74, 0x03},
                                          new byte[] {0x68, 0x07},
                                          new byte[] {0x38, 0x17}
                                      };

            for (var i = 0; i < testValues.Length; i++)
            {
                var actual = testValues[i].ToTwo7BitBytes();
                Assert.AreEqual(expectedResults[i][0], actual[0], "[{0},0] ex:{1:X2}, ac:{2:X2}", i,
                                expectedResults[i][0], actual[0]);
                Assert.AreEqual(expectedResults[i][1], actual[1], "[{0},1] ex:{1:X2}, ac:{2:X2}", i,
                                expectedResults[i][1], actual[1]);
            }
        }

        /// <summary>
        ///   Verify that nothing happens when we use Trim on an empty array.
        /// </summary>
        [TestMethod]
        public void Trim_Empty()
        {
            var emptyArray = new byte[] {};
            emptyArray.Trim();
        }

        /// <summary>
        ///   Verify that Trim does what it's supposed to do.
        /// </summary>
        [TestMethod]
        public void Trim_Functionality()
        {
            var value = new[]
                            {
                                new byte[] {0x10, 0x20, 0x30},
                                new byte[] {0xFF, 0x32, 0x10, 0x00},
                                new byte[]
                                    {0x55, 0xFE, 0xAE, 0x23, 0x59, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
                            };

            var expected = new[]
                               {
                                   new byte[] {0x10, 0x20, 0x30},
                                   new byte[] {0xFF, 0x32, 0x10},
                                   new byte[] {0x55, 0xFE, 0xAE, 0x23, 0x59, 0x12}
                               };

            var actual = new[]
                             {
                                 value[0].Trim(),
                                 value[1].Trim(),
                                 value[2].Trim()
                             };

            for (var i = 0; i < value.Length; i++)
            {
                Assert.AreEqual(expected[i].Length, actual[i].Length);
                for (var j = 0; j < expected[i].Length; j++)
                {
                    Assert.AreEqual(expected[i][j], actual[i][j]);
                }
            }
        }

        /// <summary>
        ///   Verify that the proper exception is thrown when we call Trim with a null array.
        /// </summary>
        [TestMethod]
        public void Trim_Null()
        {
            var caught = false;
            byte[] nullArray = null;

            try
            {
                nullArray.ToHexString();
            }
            catch (ArgumentNullException)
            {
                caught = true;
            }
            finally
            {
                if (!caught)
                {
                    Assert.Fail("Did not receive the expected exception.");
                }
            }
        }

        #endregion
    }
}